package operations;

import java.util.List;

import beans.Agent;
import beans.Cell;
import beans.TransDirection;

public class OnlineMovement {
	private Agent agent;
	private List<Cell> nestToFood;
	private List<Cell> snapshot;
	private Cell move;

	public OnlineMovement(Agent agent, List<Cell> nestToFood, List<Cell> snapshot) {
		this.agent = agent;
		this.nestToFood = nestToFood;
		this.snapshot = snapshot;
		process();
	}

	private void process() {
		int moveIndex = getMoveIndex();
		OnlineDecision od = new OnlineDecision(agent.getPosition(), nestToFood.get(moveIndex), snapshot, nestToFood);
		move = decideOnAMove(od, moveIndex);
	}

	private Cell decideOnAMove(OnlineDecision od, int index) {
		if (od.getAgentAtLeft()) {
			if (od.getAgentAtLeftOnline()) {
				if (od.getImportantThanLeft())
					nestToFood.get(index);
				else
					return agent.getPosition();
			} else
				return agent.getPosition(); // STAY PUT
		}
		if (od.getAgentAtRight()) {
			if (od.getAgentAtRightOnline()) {
				if (od.getImportantThanRight())
					nestToFood.get(index);
				else
					return agent.getPosition();
			} else
				return agent.getPosition(); // STAY PUT
		} else if (od.getAgentAtAdjacent()) {
			reverseDirection();
			int mindex = getMoveIndex();
			if (mindex == nestToFood.size() || mindex < 0)
				reverseDirection();
			mindex = getMoveIndex();
			OnlineDecision onLineAdj = new OnlineDecision(agent.getPosition(), nestToFood.get(mindex), snapshot, nestToFood);
			if (onLineAdj.getAgentAtLeft() || onLineAdj.getAgentAtRight() || od.getAgentAtAdjacent())
				return agent.getPosition();
			if (onLineAdj.getAgentAtHead()) {
				if (onLineAdj.getImportantThanHead())
					return nestToFood.get(mindex);
				else
					return agent.getPosition();
			}
		} else if (od.getAgentAtHead()) {
			if (od.getImportantThanHead())
				return nestToFood.get(index);
			else
				return agent.getPosition();
		} else
			return nestToFood.get(index);
		return null;
	}

	private void reverseDirection() {
		if (agent.getDirection().equals(TransDirection.TOWARDS_FOOD))
			agent.setDirection(TransDirection.TOWARDS_NEST);
		else
			agent.setDirection(TransDirection.TOWARDS_FOOD);
	}

	private int getMoveIndex() {
		if (agent.getDirection().equals(TransDirection.TOWARDS_FOOD))
			return getCurrentIndex(nestToFood) + 1;
		else
			return getCurrentIndex(nestToFood) - 1;
	}

	private int getCurrentIndex(List<Cell> path) {
		for (int i = 0; i < path.size(); i++) {
			if (path.get(i).equals(agent.getPosition()))
				return i;
		}
		return 0;
	}

	public Cell getMove() {
		return move;
	}
}
